#include "stdafx.h"
#include "Faction.h"
Faction::Faction()
{
	m_nFactionId = 0;
	m_nFactionVersion = 0;
	LOGGER_INFO("Faction:%p,m_nFactionId:%d",this,m_nFactionId);
}

Faction::Faction(FactionId nFactionId)
{
	m_nFactionId = nFactionId;
	LOGGER_INFO("Faction(FactionId nFactionId):%p,m_nFactionId:%d",this,m_nFactionId);
}
Faction::~Faction()
{
	LOGGER_INFO("~Faction:%p,m_nFactionId:%d",this,m_nFactionId);
}
void Faction::SyncFactionInfo()
{
	encodeTrends();
	PacketEncoder encoder;
	encoder.AddItem(Int32(0));
	encoder.AddItem(Int32(1804));

	encoder.AddItem(m_stFactionInfo.m_nFactionId);
	DataBlock blkInfo;
	blkInfo.AppendData(&m_stFactionInfo,sizeof(m_stFactionInfo));
	encoder.AddItem(blkInfo);
	SendPacketToData(encoder);
}
void Faction::SetFactionInfo(FactionInfo& info)
{
	info.m_szFactionName[MAX_FACTION_NAME_SIZE-1] = '\0';
	info.m_szMasterCharName[MAX_CHAR_NAME_SIZE-1] = '\0';
	info.m_szTenet[MAX_FACTION_TENET_SIZE-1] = '\0';
	info.m_szNotice[MAX_FACTION_NOTICE_SIZE-1] = '\0';

	m_stFactionInfo = info;

	if(m_stFactionInfo.m_nMembersSize < 0 || m_stFactionInfo.m_nMembersSize > MAX_FACTION_MEMBERS_SIZE)
	{
		m_stFactionInfo.m_nMembersSize = 0;
	}
	decodeTrends();
	m_nFactionVersion++;
}

FactionInfo::MemberInfo* Faction::GetMemberInfo(Int32 nCharId)
{
	if(m_stFactionInfo.m_nMembersSize < 0 || m_stFactionInfo.m_nMembersSize > MAX_FACTION_MEMBERS_SIZE)
	{
		m_stFactionInfo.m_nMembersSize = 0;
		return NULL;
	}

	for (Int32 i = 0; i < m_stFactionInfo.m_nMembersSize; i++)
	{
		if (nCharId == m_stFactionInfo.m_arMembers[i].m_nCharId)
		{
			return &(m_stFactionInfo.m_arMembers[i]);
		}
	}
	return NULL;
}
bool Faction::HasMember(Int32 nCharId)
{
	return GetMemberInfo(nCharId) != NULL;
}
bool Faction::AddMember(FactionInfo::ApplicantInfo& infoApplicant,Int32 nJob)
{
	if (HasMember(infoApplicant.m_nCharId))
	{
		return true;
	}
	if(m_stFactionInfo.m_nMembersSize < 0 || m_stFactionInfo.m_nMembersSize > MAX_FACTION_MEMBERS_SIZE)
	{
		m_stFactionInfo.m_nMembersSize = 0;
		return NULL;
	}

	if(m_stFactionInfo.m_nMembersSize >= MAX_FACTION_MEMBERS_SIZE)
	{
		LOGGER_INFO("AddMember,m_stFactionInfo.m_nMembersSize >= MAX_FACTION_MEMBERS_SIZE");
		return false;
	}
	FactionInfo::MemberInfo& info = m_stFactionInfo.m_arMembers[m_stFactionInfo.m_nMembersSize];
	info.m_nCharId = infoApplicant.m_nCharId;
	info.m_szCharName[MAX_CHAR_NAME_SIZE - 1] = '\0';
	infoApplicant.m_szCharName[MAX_CHAR_NAME_SIZE - 1] = '\0';
	strcpy(info.m_szCharName,infoApplicant.m_szCharName);
	info.m_nLevel = infoApplicant.m_nLevel;
	info.m_nRace = infoApplicant.m_nRace;
	info.m_nGender = infoApplicant.m_nGender;
	info.m_nJob = nJob;
	info.m_nJoinTime = Int32(time(NULL));

	//pPlayer->m_stCharInfo.m_nFactionId = m_stFactionInfo.m_nFactionId;
	//pPlayer->m_stCharInfo.m_szFactionName[MAX_FACTION_NAME_SIZE - 1] = '\0';
	//m_stFactionInfo.m_szFactionName[MAX_FACTION_NAME_SIZE - 1] = '\0';
	//strcpy(pPlayer->m_stCharInfo.m_szFactionName,m_stFactionInfo.m_szFactionName);

	m_stFactionInfo.m_nMembersSize += 1;
	singleton<FactionManager>::instance().m_nFactionVersion++;
	m_nFactionVersion++;
	return true;
}
bool Faction::AddMember(Int32 nCharId,Int32 nJob)
{
	if (HasMember(nCharId))
	{
		return true;
	}

	if(m_stFactionInfo.m_nMembersSize < 0 || m_stFactionInfo.m_nMembersSize > MAX_FACTION_MEMBERS_SIZE)
	{
		m_stFactionInfo.m_nMembersSize = 0;
		return NULL;
	}

	if(m_stFactionInfo.m_nMembersSize >= MAX_FACTION_MEMBERS_SIZE)
	{
		LOGGER_INFO("AddMember,m_stFactionInfo.m_nMembersSize >= MAX_FACTION_MEMBERS_SIZE");
		return false;
	}
	Player* pPlayer = singleton<PlayerManager>::instance().GetByCharId(nCharId);
	if (pPlayer == NULL)
	{
		return false;
	}

	FactionInfo::MemberInfo& info = m_stFactionInfo.m_arMembers[m_stFactionInfo.m_nMembersSize];
	info.m_nCharId = nCharId;
	info.m_szCharName[MAX_CHAR_NAME_SIZE - 1] = '\0';
	if(!pPlayer->m_strCharName.empty() && pPlayer->m_strCharName.size() < MAX_CHAR_NAME_SIZE)
		strcpy(info.m_szCharName,pPlayer->m_strCharName.c_str());
	info.m_nLevel = pPlayer->m_nLevel;
	info.m_nRace = pPlayer->m_nRace;
	info.m_nGender = pPlayer->m_nGender;
	info.m_nJob = nJob;
	info.m_nJoinTime = Int32(time(NULL));

	pPlayer->m_stCharInfo.m_nFactionId = m_stFactionInfo.m_nFactionId;
	pPlayer->m_stCharInfo.m_szFactionName[MAX_FACTION_NAME_SIZE - 1] = '\0';
	m_stFactionInfo.m_szFactionName[MAX_FACTION_NAME_SIZE - 1] = '\0';
	strcpy(pPlayer->m_stCharInfo.m_szFactionName,m_stFactionInfo.m_szFactionName);

	m_stFactionInfo.m_nMembersSize += 1;
	singleton<FactionManager>::instance().m_nFactionVersion++;
	m_nFactionVersion++;
	return true;
}
bool Faction::RemoveMember(Int32 nCharId)
{
	bool bRemove = false;
	Int32 nIndex = 0;
	for (Int32 i = 0; i < m_stFactionInfo.m_nMembersSize; i++)
	{
		if (nCharId == m_stFactionInfo.m_arMembers[i].m_nCharId)
		{
			m_stFactionInfo.m_arMembers[i].m_nCharId = 0;
			nIndex = i;
			bRemove = true;
			break;
		}
	}

	if (bRemove)
	{
		for (Int32 i = nIndex; i < m_stFactionInfo.m_nMembersSize - 1; i++)
		{
			m_stFactionInfo.m_arMembers[i] = m_stFactionInfo.m_arMembers[i+1];
		}
		m_stFactionInfo.m_nMembersSize -= 1;
		singleton<FactionManager>::instance().m_nFactionVersion++;
		m_nFactionVersion++;
	}
	return bRemove;
}

FactionInfo::ApplicantInfo* Faction::GetApplicantInfo(Int32 nCharId)
{
	if(m_stFactionInfo.m_nApplicantsSize < 0 || m_stFactionInfo.m_nApplicantsSize > MAX_FACTION_MEMBERS_SIZE)
	{
		m_stFactionInfo.m_nApplicantsSize = 0;
		return NULL;
	}

	for (Int32 i = 0; i < m_stFactionInfo.m_nApplicantsSize; i++)
	{
		if (nCharId == m_stFactionInfo.m_arApplicants[i].m_nCharId)
		{
			return &(m_stFactionInfo.m_arApplicants[i]);
		}
	}
	return NULL;
}
bool Faction::HasApplicant(Int32 nCharId)
{
	return GetApplicantInfo(nCharId) != NULL;
}
bool Faction::AddApplicant(Int32 nCharId)
{
	if (HasApplicant(nCharId))
	{
		return true;
	}

	if(m_stFactionInfo.m_nApplicantsSize < 0 || m_stFactionInfo.m_nApplicantsSize > MAX_FACTION_APPLICANTS_SIZE)
	{
		m_stFactionInfo.m_nApplicantsSize = 0;
		return NULL;
	}

	if(m_stFactionInfo.m_nApplicantsSize >= MAX_FACTION_APPLICANTS_SIZE)
	{
		LOGGER_INFO("AddApplicant,m_stFactionInfo.m_nApplicantsSize >= MAX_FACTION_APPLICANTS_SIZE");
		return false;
	}
	Player* pPlayer = singleton<PlayerManager>::instance().GetByCharId(nCharId);
	if (pPlayer == NULL)
	{
		return false;
	}

	FactionInfo::ApplicantInfo& info = m_stFactionInfo.m_arApplicants[m_stFactionInfo.m_nApplicantsSize];
	info.m_nCharId = nCharId;
	info.m_szCharName[MAX_CHAR_NAME_SIZE - 1] = '\0';
	if(!pPlayer->m_strCharName.empty() && pPlayer->m_strCharName.size() < MAX_CHAR_NAME_SIZE)
		strcpy(info.m_szCharName,pPlayer->m_strCharName.c_str());
	info.m_nLevel = pPlayer->m_nLevel;
	info.m_nRace = pPlayer->m_nRace;
	info.m_nGender = pPlayer->m_nGender;
	info.m_nApplicantTime = Int32(time(NULL));
	m_stFactionInfo.m_nApplicantsSize += 1;
	m_nFactionVersion++;
	return true;
}
bool Faction::RemoveApplicant(Int32 nCharId)
{
	bool bRemove = false;
	Int32 nIndex = 0;
	for (Int32 i = 0; i < m_stFactionInfo.m_nApplicantsSize; i++)
	{
		if (nCharId == m_stFactionInfo.m_arApplicants[i].m_nCharId)
		{
			m_stFactionInfo.m_arApplicants[i].m_nCharId = 0;
			nIndex = i;
			bRemove = true;
			break;
		}
	}

	if (bRemove)
	{
		for (Int32 i = nIndex; i < m_stFactionInfo.m_nApplicantsSize - 1; i++)
		{
			m_stFactionInfo.m_arApplicants[i] = m_stFactionInfo.m_arApplicants[i+1];
		}
		m_stFactionInfo.m_nApplicantsSize -= 1;
		m_nFactionVersion++;
	}
	return bRemove;
}
/*bool AddApplicant(Int32 nCharId);
bool RemoveApplicant(Int32 nCharId);
bool HasApplicant(Int32 nCharId);*/
void Faction::encodeMembers(PacketEncoder& encoder)
{
	if(m_stFactionInfo.m_nMembersSize < 0 || m_stFactionInfo.m_nMembersSize > MAX_FACTION_MEMBERS_SIZE)
	{
		m_stFactionInfo.m_nMembersSize = 0;
	}

	encoder.AddItem(m_stFactionInfo.m_nMembersSize);
	for (Int32 i = 0; i < m_stFactionInfo.m_nMembersSize; i++)
	{
		FactionInfo::MemberInfo& info = m_stFactionInfo.m_arMembers[i];
		encoder.AddItem(info.m_nCharId);
		info.m_szCharName[MAX_CHAR_NAME_SIZE -1] = '\0';
		encoder.AddItem(info.m_szCharName);
		encoder.AddItem(info.m_nLevel);
		encoder.AddItem(info.m_nRace);
		encoder.AddItem(info.m_nGender);
		encoder.AddItem(info.m_nJob);
		encoder.AddItem(info.m_nDevote);
		encoder.AddItem(FormatTimeShort(info.m_nJoinTime));
	}
}

void Faction::encodeApplicants(PacketEncoder& encoder)
{
	if(m_stFactionInfo.m_nApplicantsSize < 0 || m_stFactionInfo.m_nApplicantsSize > MAX_FACTION_MEMBERS_SIZE)
	{
		m_stFactionInfo.m_nApplicantsSize = 0;
	}

	encoder.AddItem(m_stFactionInfo.m_nApplicantsSize);
	for (Int32 i = 0; i < m_stFactionInfo.m_nApplicantsSize; i++)
	{
		FactionInfo::ApplicantInfo& info = m_stFactionInfo.m_arApplicants[i];
		encoder.AddItem(info.m_nCharId);
		info.m_szCharName[MAX_CHAR_NAME_SIZE -1] = '\0';
		encoder.AddItem(info.m_szCharName);
		encoder.AddItem(info.m_nLevel);
		encoder.AddItem(info.m_nRace);
		encoder.AddItem(info.m_nGender);
		encoder.AddItem(FormatTimeMinute(info.m_nApplicantTime));
	}
}
void Faction::decodeTrends()
{
	if(m_stFactionInfo.m_nTrendsSize < 0)
		m_stFactionInfo.m_nTrendsSize = 0;
	if (m_stFactionInfo.m_nTrendsSize > MAX_FACTION_TRENDS_SIZE)
	{
		LOGGER_ERROR("Faction::decodeTrends,m_stFactionInfo.m_nTrendsSize >= MAX_FACTION_TRENDS_SIZE");
		return;
	}

	m_listTrends.clear();
	for (Int32 i = 0; i < m_stFactionInfo.m_nTrendsSize; i++)
	{
		if (m_stFactionInfo.m_arTrends[i].m_szMessage[0] != '\0')
		{
			m_stFactionInfo.m_arTrends[i].m_szMessage[FactionInfo::MAX_TREND_LENGTH-1] = '\0';
			m_listTrends.push_back(m_stFactionInfo.m_arTrends[i]);
			if(singleton<PlayerManager>::instance().getWorldTrendsCount() < 30)
				singleton<PlayerManager>::instance().addWorldTrends("<font color=\"#999999\">"+FormatTimeMinute(m_stFactionInfo.m_arTrends[i].m_tTime)+"</font> " + std::string(m_stFactionInfo.m_szFactionName)+":"+m_stFactionInfo.m_arTrends[i].m_szMessage);
		}
	}
}
void Faction::encodeTrends()
{
	if (m_listTrends.size() > MAX_FACTION_TRENDS_SIZE)
	{
		LOGGER_ERROR("Faction::encodeTrends,m_listTrends.size() >= MAX_FACTION_TRENDS_SIZE");
		return;
	}
	m_stFactionInfo.m_nTrendsSize = Int32(m_listTrends.size());
	Int32 i = 0;
	std::list<FactionInfo::TrendInfo>::iterator iter = m_listTrends.begin();
	std::list<FactionInfo::TrendInfo>::iterator iterend = m_listTrends.end();
	for (; iter != iterend; iter++)
	{
		m_stFactionInfo.m_arTrends[i++] = *iter;
	}
}
void Faction::addTrends(std::string message,bool bAddToWorld)
{
	if (message.size() >= FactionInfo::MAX_TREND_LENGTH)
	{
		LOGGER_ERROR("Faction::addTrends,message.size() >= FactionInfo::MAX_TREND_LENGTH");
		return;
	}
	m_listTrends.push_back(FactionInfo::TrendInfo());
	FactionInfo::TrendInfo& trend = m_listTrends.back();
	strcpy(trend.m_szMessage,message.c_str());
	trend.m_tTime = Int32(time(NULL));
	while (m_listTrends.size() > MAX_FACTION_TRENDS_SIZE)
	{
		std::list<FactionInfo::TrendInfo>::iterator iter = m_listTrends.begin();
		m_listTrends.pop_front();
	}
	//PrepareSendTrends();
	m_nFactionVersion++;
	if(bAddToWorld)
		singleton<PlayerManager>::instance().addWorldTrends("<font color=\"#999999\">"+FormatTimeMinute(trend.m_tTime)+"</font> " + std::string(m_stFactionInfo.m_szFactionName)+":"+message);
}
void Faction::SendPacketToAll(PacketEncoder& encoder)
{
	for (Int32 i = 0; i < m_stFactionInfo.m_nMembersSize; i++)
	{
		Player* pPlayer = singleton<PlayerManager>::instance().GetByCharId(m_stFactionInfo.m_arMembers[i].m_nCharId);
		if (pPlayer != NULL)
		{
			pPlayer->SendPacketToPlayer(encoder);
		}
	}
}